home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / calc202a.lha / calc-2.02a / calc-funcs.el < prev    next >
Lisp/Scheme  |  1993-06-01  |  30KB  |  1,035 lines

  1. ;; Calculator for GNU Emacs, part II [calc-funcs.el]
  2. ;; Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
  3. ;; Written by Dave Gillespie, daveg@synaptics.com.
  4.  
  5. ;; This file is part of GNU Emacs.
  6.  
  7. ;; GNU Emacs is distributed in the hope that it will be useful,
  8. ;; but WITHOUT ANY WARRANTY.  No author or distributor
  9. ;; accepts responsibility to anyone for the consequences of using it
  10. ;; or for whether it serves any particular purpose or works at all,
  11. ;; unless he says so in writing.  Refer to the GNU Emacs General Public
  12. ;; License for full details.
  13.  
  14. ;; Everyone is granted permission to copy, modify and redistribute
  15. ;; GNU Emacs, but only under the conditions described in the
  16. ;; GNU Emacs General Public License.   A copy of this license is
  17. ;; supposed to have been given to you along with GNU Emacs so you
  18. ;; can know your rights and responsibilities.  It should be in a
  19. ;; file named COPYING.  Among other things, the copyright notice
  20. ;; and this notice must be preserved on all copies.
  21.  
  22.  
  23.  
  24. ;; This file is autoloaded from calc-ext.el.
  25. (require 'calc-ext)
  26.  
  27. (require 'calc-macs)
  28.  
  29. (defun calc-Need-calc-funcs () nil)
  30.  
  31.  
  32. (defun calc-inc-gamma (arg)
  33.   (interactive "P")
  34.   (calc-slow-wrapper
  35.    (if (calc-is-inverse)
  36.        (if (calc-is-hyperbolic)
  37.        (calc-binary-op "gamG" 'calcFunc-gammaG arg)
  38.      (calc-binary-op "gamQ" 'calcFunc-gammaQ arg))
  39.        (if (calc-is-hyperbolic)
  40.        (calc-binary-op "gamg" 'calcFunc-gammag arg)
  41.      (calc-binary-op "gamP" 'calcFunc-gammaP arg))))
  42. )
  43.  
  44. (defun calc-erf (arg)
  45.   (interactive "P")
  46.   (calc-slow-wrapper
  47.    (if (calc-is-inverse)
  48.        (calc-unary-op "erfc" 'calcFunc-erfc arg)
  49.      (calc-unary-op "erf" 'calcFunc-erf arg)))
  50. )
  51.  
  52. (defun calc-erfc (arg)
  53.   (interactive "P")
  54.   (calc-invert-func)
  55.   (calc-erf arg)
  56. )
  57.  
  58. (defun calc-beta (arg)
  59.   (interactive "P")
  60.   (calc-slow-wrapper
  61.    (calc-binary-op "beta" 'calcFunc-beta arg))
  62. )
  63.  
  64. (defun calc-inc-beta ()
  65.   (interactive)
  66.   (calc-slow-wrapper
  67.    (if (calc-is-hyperbolic)
  68.        (calc-enter-result 3 "betB" (cons 'calcFunc-betaB (calc-top-list-n 3)))
  69.      (calc-enter-result 3 "betI" (cons 'calcFunc-betaI (calc-top-list-n 3)))))
  70. )
  71.  
  72. (defun calc-bessel-J (arg)
  73.   (interactive "P")
  74.   (calc-slow-wrapper
  75.    (calc-binary-op "besJ" 'calcFunc-besJ arg))
  76. )
  77.  
  78. (defun calc-bessel-Y (arg)
  79.   (interactive "P")
  80.   (calc-slow-wrapper
  81.    (calc-binary-op "besY" 'calcFunc-besY arg))
  82. )
  83.  
  84. (defun calc-bernoulli-number (arg)
  85.   (interactive "P")
  86.   (calc-slow-wrapper
  87.    (if (calc-is-hyperbolic)
  88.        (calc-binary-op "bern" 'calcFunc-bern arg)
  89.      (calc-unary-op "bern" 'calcFunc-bern arg)))
  90. )
  91.  
  92. (defun calc-euler-number (arg)
  93.   (interactive "P")
  94.   (calc-slow-wrapper
  95.    (if (calc-is-hyperbolic)
  96.        (calc-binary-op "eulr" 'calcFunc-euler arg)
  97.      (calc-unary-op "eulr" 'calcFunc-euler arg)))
  98. )
  99.  
  100. (defun calc-stirling-number (arg)
  101.   (interactive "P")
  102.   (calc-slow-wrapper
  103.    (if (calc-is-hyperbolic)
  104.        (calc-binary-op "str2" 'calcFunc-stir2 arg)
  105.      (calc-binary-op "str1" 'calcFunc-stir1 arg)))
  106. )
  107.  
  108. (defun calc-utpb ()
  109.   (interactive)
  110.   (calc-prob-dist "b" 3)
  111. )
  112.  
  113. (defun calc-utpc ()
  114.   (interactive)
  115.   (calc-prob-dist "c" 2)
  116. )
  117.  
  118. (defun calc-utpf ()
  119.   (interactive)
  120.   (calc-prob-dist "f" 3)
  121. )
  122.  
  123. (defun calc-utpn ()
  124.   (interactive)
  125.   (calc-prob-dist "n" 3)
  126. )
  127.  
  128. (defun calc-utpp ()
  129.   (interactive)
  130.   (calc-prob-dist "p" 2)
  131. )
  132.  
  133. (defun calc-utpt ()
  134.   (interactive)
  135.   (calc-prob-dist "t" 2)
  136. )
  137.  
  138. (defun calc-prob-dist (letter nargs)
  139.   (calc-slow-wrapper
  140.    (if (calc-is-inverse)
  141.        (calc-enter-result nargs (concat "ltp" letter)
  142.               (append (list (intern (concat "calcFunc-ltp" letter))
  143.                     (calc-top-n 1))
  144.                   (calc-top-list-n (1- nargs) 2)))
  145.      (calc-enter-result nargs (concat "utp" letter)
  146.             (append (list (intern (concat "calcFunc-utp" letter))
  147.                       (calc-top-n 1))
  148.                 (calc-top-list-n (1- nargs) 2)))))
  149. )
  150.  
  151.  
  152.  
  153.  
  154. ;;; Sources:  Numerical Recipes, Press et al;
  155. ;;;           Handbook of Mathematical Functions, Abramowitz & Stegun.
  156.  
  157.  
  158. ;;; Gamma function.
  159.  
  160. (defun calcFunc-gamma (x)
  161.   (or (math-numberp x) (math-reject-arg x 'numberp))
  162.   (calcFunc-fact (math-add x -1))
  163. )
  164.  
  165. (defun math-gammap1-raw (x &optional fprec nfprec)   ; compute gamma(1 + x)
  166.   (or fprec
  167.       (setq fprec (math-float calc-internal-prec)
  168.         nfprec (math-float (- calc-internal-prec))))
  169.   (cond ((math-lessp-float (calcFunc-re x) fprec)
  170.      (if (math-lessp-float (calcFunc-re x) nfprec)
  171.          (math-neg (math-div
  172.             (math-pi)
  173.             (math-mul (math-gammap1-raw
  174.                    (math-add (math-neg x)
  175.                          '(float -1 0))
  176.                    fprec nfprec)
  177.                   (math-sin-raw
  178.                    (math-mul (math-pi) x)))))
  179.        (let ((xplus1 (math-add x '(float 1 0))))
  180.          (math-div (math-gammap1-raw xplus1 fprec nfprec) xplus1))))
  181.     ((and (math-realp x)
  182.           (math-lessp-float '(float 736276 0) x))
  183.      (math-overflow))
  184.     (t   ; re(x) now >= 10.0
  185.      (let ((xinv (math-div 1 x))
  186.            (lnx (math-ln-raw x)))
  187.        (math-mul (math-sqrt-two-pi)
  188.              (math-exp-raw
  189.               (math-gamma-series
  190.                (math-sub (math-mul (math-add x '(float 5 -1))
  191.                        lnx)
  192.                  x)
  193.                xinv
  194.                (math-sqr xinv)
  195.                '(float 0 0)
  196.                2))))))
  197. )
  198.  
  199. (defun math-gamma-series (sum x xinvsqr oterm n)
  200.   (math-working "gamma" sum)
  201.   (let* ((bn (math-bernoulli-number n))
  202.      (term (math-mul (math-div-float (math-float (nth 1 bn))
  203.                      (math-float (* (nth 2 bn)
  204.                             (* n (1- n)))))
  205.              x))
  206.      (next (math-add sum term)))
  207.     (if (math-nearly-equal sum next)
  208.     next
  209.       (if (> n (* 2 calc-internal-prec))
  210.       (progn
  211.         ;; Need this because series eventually diverges for large enough n.
  212.         (calc-record-why
  213.          "*Gamma computation stopped early, not all digits may be valid")
  214.         next)
  215.     (math-gamma-series next (math-mul x xinvsqr) xinvsqr term (+ n 2)))))
  216. )
  217.  
  218.  
  219. ;;; Incomplete gamma function.
  220.  
  221. (defun calcFunc-gammaP (a x)
  222.   (if (equal x '(var inf var-inf))
  223.       '(float 1 0)
  224.     (math-inexact-result)
  225.     (or (Math-numberp a) (math-reject-arg a 'numberp))
  226.     (or (math-numberp x) (math-reject-arg x 'numberp))
  227.     (if (and (math-num-integerp a)
  228.          (integerp (setq a (math-trunc a)))
  229.          (> a 0) (< a 20))
  230.     (math-sub 1 (calcFunc-gammaQ a x))
  231.       (let ((math-current-gamma-value (calcFunc-gamma a)))
  232.     (math-div (calcFunc-gammag a x) math-current-gamma-value))))
  233. )
  234.  
  235. (defun calcFunc-gammaQ (a x)
  236.   (if (equal x '(var inf var-inf))
  237.       '(float 0 0)
  238.     (math-inexact-result)
  239.     (or (Math-numberp a) (math-reject-arg a 'numberp))
  240.     (or (math-numberp x) (math-reject-arg x 'numberp))
  241.     (if (and (math-num-integerp a)
  242.          (integerp (setq a (math-trunc a)))
  243.          (> a 0) (< a 20))
  244.     (let ((n 0)
  245.           (sum '(float 1 0))
  246.           (term '(float 1 0)))
  247.       (math-with-extra-prec 1
  248.         (while (< (setq n (1+ n)) a)
  249.           (setq term (math-div (math-mul term x) n)
  250.             sum (math-add sum term))
  251.           (math-working "gamma" sum))
  252.         (math-mul sum (calcFunc-exp (math-neg x)))))
  253.       (let ((math-current-gamma-value (calcFunc-gamma a)))
  254.     (math-div (calcFunc-gammaG a x) math-current-gamma-value))))
  255. )
  256.  
  257. (defun calcFunc-gammag (a x)
  258.   (if (equal x '(var inf var-inf))
  259.       (calcFunc-gamma a)
  260.     (math-inexact-result)
  261.     (or (Math-numberp a) (math-reject-arg a 'numberp))
  262.     (or (Math-numberp x) (math-reject-arg x 'numberp))
  263.     (math-with-extra-prec 2
  264.       (setq a (math-float a))
  265.       (setq x (math-float x))
  266.       (if (or (math-negp (calcFunc-re a))
  267.           (math-lessp-float (calcFunc-re x)
  268.                 (math-add-float (calcFunc-re a)
  269.                         '(float 1 0))))
  270.       (math-inc-gamma-series a x)
  271.     (math-sub (or math-current-gamma-value (calcFunc-gamma a))
  272.           (math-inc-gamma-cfrac a x)))))
  273. )
  274. (setq math-current-gamma-value nil)
  275.  
  276. (defun calcFunc-gammaG (a x)
  277.   (if (equal x '(var inf var-inf))
  278.       '(float 0 0)
  279.     (math-inexact-result)
  280.     (or (Math-numberp a) (math-reject-arg a 'numberp))
  281.     (or (Math-numberp x) (math-reject-arg x 'numberp))
  282.     (math-with-extra-prec 2
  283.       (setq a (math-float a))
  284.       (setq x (math-float x))
  285.       (if (or (math-negp (calcFunc-re a))
  286.           (math-lessp-float (calcFunc-re x)
  287.                 (math-add-float (math-abs-approx a)
  288.                         '(float 1 0))))
  289.       (math-sub (or math-current-gamma-value (calcFunc-gamma a))
  290.             (math-inc-gamma-series a x))
  291.     (math-inc-gamma-cfrac a x))))
  292. )
  293.  
  294. (defun math-inc-gamma-series (a x)
  295.   (if (Math-zerop x)
  296.       '(float 0 0)
  297.     (math-mul (math-exp-raw (math-sub (math-mul a (math-ln-raw x)) x))
  298.           (math-with-extra-prec 2
  299.         (let ((start (math-div '(float 1 0) a)))
  300.           (math-inc-gamma-series-step start start a x)))))
  301. )
  302.  
  303. (defun math-inc-gamma-series-step (sum term a x)
  304.   (math-working "gamma" sum)
  305.   (setq a (math-add a '(float 1 0))
  306.     term (math-div (math-mul term x) a))
  307.   (let ((next (math-add sum term)))
  308.     (if (math-nearly-equal sum next)
  309.     next
  310.       (math-inc-gamma-series-step next term a x)))
  311. )
  312.  
  313. (defun math-inc-gamma-cfrac (a x)
  314.   (if (Math-zerop x)
  315.       (or math-current-gamma-value (calcFunc-gamma a))
  316.     (math-mul (math-exp-raw (math-sub (math-mul a (math-ln-raw x)) x))
  317.           (math-inc-gamma-cfrac-step '(float 1 0) x
  318.                      '(float 0 0) '(float 1 0)
  319.                      '(float 1 0) '(float 1 0) '(float 0 0)
  320.                      a x)))
  321. )
  322.  
  323. (defun math-inc-gamma-cfrac-step (a0 a1 b0 b1 n fac g a x)
  324.   (let ((ana (math-sub n a))
  325.     (anf (math-mul n fac)))
  326.     (setq n (math-add n '(float 1 0))
  327.       a0 (math-mul (math-add a1 (math-mul a0 ana)) fac)
  328.       b0 (math-mul (math-add b1 (math-mul b0 ana)) fac)
  329.       a1 (math-add (math-mul x a0) (math-mul anf a1))
  330.       b1 (math-add (math-mul x b0) (math-mul anf b1)))
  331.     (if (math-zerop a1)
  332.     (math-inc-gamma-cfrac-step a0 a1 b0 b1 n fac g a x)
  333.       (setq fac (math-div '(float 1 0) a1))
  334.       (let ((next (math-mul b1 fac)))
  335.     (math-working "gamma" next)
  336.     (if (math-nearly-equal next g)
  337.         next
  338.       (math-inc-gamma-cfrac-step a0 a1 b0 b1 n fac next a x)))))
  339. )
  340.  
  341.  
  342. ;;; Error function.
  343.  
  344. (defun calcFunc-erf (x)
  345.   (if (equal x '(var inf var-inf))
  346.       '(float 1 0)
  347.     (if (equal x '(neg (var inf var-inf)))
  348.     '(float -1 0)
  349.       (if (Math-zerop x)
  350.       x
  351.     (let ((math-current-gamma-value (math-sqrt-pi)))
  352.       (math-to-same-complex-quad
  353.        (math-div (calcFunc-gammag '(float 5 -1)
  354.                       (math-sqr (math-to-complex-quad-one x)))
  355.              math-current-gamma-value)
  356.        x)))))
  357. )
  358.  
  359. (defun calcFunc-erfc (x)
  360.   (if (equal x '(var inf var-inf))
  361.       '(float 0 0)
  362.     (if (math-posp x)
  363.     (let ((math-current-gamma-value (math-sqrt-pi)))
  364.       (math-div (calcFunc-gammaG '(float 5 -1) (math-sqr x))
  365.             math-current-gamma-value))
  366.       (math-sub 1 (calcFunc-erf x))))
  367. )
  368.  
  369. (defun math-to-complex-quad-one (x)
  370.   (if (eq (car-safe x) 'polar) (setq x (math-complex x)))
  371.   (if (eq (car-safe x) 'cplx)
  372.       (list 'cplx (math-abs (nth 1 x)) (math-abs (nth 2 x)))
  373.     x)
  374. )
  375.  
  376. (defun math-to-same-complex-quad (x y)
  377.   (if (eq (car-safe y) 'cplx)
  378.       (if (eq (car-safe x) 'cplx)
  379.       (list 'cplx
  380.         (if (math-negp (nth 1 y)) (math-neg (nth 1 x)) (nth 1 x))
  381.         (if (math-negp (nth 2 y)) (math-neg (nth 2 x)) (nth 2 x)))
  382.     (if (math-negp (nth 1 y)) (math-neg x) x))
  383.     (if (math-negp y)
  384.     (if (eq (car-safe x) 'cplx)
  385.         (list 'cplx (math-neg (nth 1 x)) (nth 2 x))
  386.       (math-neg x))
  387.       x))
  388. )
  389.  
  390.  
  391. ;;; Beta function.
  392.  
  393. (defun calcFunc-beta (a b)
  394.   (if (math-num-integerp a)
  395.       (let ((am (math-add a -1)))
  396.     (or (math-numberp b) (math-reject-arg b 'numberp))
  397.     (math-div 1 (math-mul b (calcFunc-choose (math-add b am) am))))
  398.     (if (math-num-integerp b)
  399.     (calcFunc-beta b a)
  400.       (math-div (math-mul (calcFunc-gamma a) (calcFunc-gamma b))
  401.         (calcFunc-gamma (math-add a b)))))
  402. )
  403.  
  404.  
  405. ;;; Incomplete beta function.
  406.  
  407. (defun calcFunc-betaI (x a b)
  408.   (cond ((math-zerop x)
  409.      '(float 0 0))
  410.     ((math-equal-int x 1)
  411.      '(float 1 0))
  412.     ((or (math-zerop a)
  413.          (and (math-num-integerp a)
  414.           (math-negp a)))
  415.      (if (or (math-zerop b)
  416.          (and (math-num-integerp b)
  417.               (math-negp b)))
  418.          (math-reject-arg b 'range)
  419.        '(float 1 0)))
  420.     ((or (math-zerop b)
  421.          (and (math-num-integerp b)
  422.           (math-negp b)))
  423.      '(float 0 0))
  424.     ((not (math-numberp a)) (math-reject-arg a 'numberp))
  425.     ((not (math-numberp b)) (math-reject-arg b 'numberp))
  426.     ((math-inexact-result))
  427.     (t (let ((math-current-beta-value (calcFunc-beta a b)))
  428.          (math-div (calcFunc-betaB x a b) math-current-beta-value))))
  429. )
  430.  
  431. (defun calcFunc-betaB (x a b)
  432.   (cond
  433.    ((math-zerop x)
  434.     '(float 0 0))
  435.    ((math-equal-int x 1)
  436.     (calcFunc-beta a b))
  437.    ((not (math-numberp x)) (math-reject-arg x 'numberp))
  438.    ((not (math-numberp a)) (math-reject-arg a 'numberp))
  439.    ((not (math-numberp b)) (math-reject-arg b 'numberp))
  440.    ((math-zerop a) (math-reject-arg a 'nonzerop))
  441.    ((math-zerop b) (math-reject-arg b 'nonzerop))
  442.    ((and (math-num-integerp b)
  443.      (if (math-negp b)
  444.          (math-reject-arg b 'range)
  445.        (Math-natnum-lessp (setq b (math-trunc b)) 20)))
  446.     (and calc-symbolic-mode (or (math-floatp a) (math-floatp b))
  447.      (math-inexact-result))
  448.     (math-mul
  449.      (math-with-extra-prec 2
  450.        (let* ((i 0)
  451.           (term 1)
  452.           (sum (math-div term a)))
  453.      (while (< (setq i (1+ i)) b)
  454.        (setq term (math-mul (math-div (math-mul term (- i b)) i) x)
  455.          sum (math-add sum (math-div term (math-add a i))))
  456.        (math-working "beta" sum))
  457.      sum))
  458.      (math-pow x a)))
  459.    ((and (math-num-integerp a)
  460.      (if (math-negp a)
  461.          (math-reject-arg a 'range)
  462.        (Math-natnum-lessp (setq a (math-trunc a)) 20)))
  463.     (math-sub (or math-current-beta-value (calcFunc-beta a b))
  464.           (calcFunc-betaB (math-sub 1 x) b a)))
  465.    (t
  466.     (math-inexact-result)
  467.     (math-with-extra-prec 2
  468.       (setq x (math-float x))
  469.       (setq a (math-float a))
  470.       (setq b (math-float b))
  471.       (let ((bt (math-exp-raw (math-add (math-mul a (math-ln-raw x))
  472.                     (math-mul b (math-ln-raw
  473.                              (math-sub '(float 1 0)
  474.                                    x)))))))
  475.     (if (Math-lessp x (math-div (math-add a '(float 1 0))
  476.                     (math-add (math-add a b) '(float 2 0))))
  477.         (math-div (math-mul bt (math-beta-cfrac a b x)) a)
  478.       (math-sub (or math-current-beta-value (calcFunc-beta a b))
  479.             (math-div (math-mul bt
  480.                     (math-beta-cfrac b a (math-sub 1 x)))
  481.                   b)))))))
  482. )
  483. (setq math-current-beta-value nil)
  484.  
  485. (defun math-beta-cfrac (a b x)
  486.   (let ((qab (math-add a b))
  487.     (qap (math-add a '(float 1 0)))
  488.     (qam (math-add a '(float -1 0))))
  489.     (math-beta-cfrac-step '(float 1 0)
  490.               (math-sub '(float 1 0)
  491.                     (math-div (math-mul qab x) qap))
  492.               '(float 1 0) '(float 1 0)
  493.               '(float 1 0)
  494.               qab qap qam a b x))
  495. )
  496.  
  497. (defun math-beta-cfrac-step (az bz am bm m qab qap qam a b x)
  498.   (let* ((two-m (math-mul m '(float 2 0)))
  499.      (d (math-div (math-mul (math-mul (math-sub b m) m) x)
  500.               (math-mul (math-add qam two-m) (math-add a two-m))))
  501.      (ap (math-add az (math-mul d am)))
  502.      (bp (math-add bz (math-mul d bm)))
  503.      (d2 (math-neg
  504.           (math-div (math-mul (math-mul (math-add a m) (math-add qab m)) x)
  505.             (math-mul (math-add qap two-m) (math-add a two-m)))))
  506.      (app (math-add ap (math-mul d2 az)))
  507.      (bpp (math-add bp (math-mul d2 bz)))
  508.      (next (math-div app bpp)))
  509.     (math-working "beta" next)
  510.     (if (math-nearly-equal next az)
  511.     next
  512.       (math-beta-cfrac-step next '(float 1 0)
  513.                 (math-div ap bpp) (math-div bp bpp)
  514.                 (math-add m '(float 1 0))
  515.                 qab qap qam a b x)))
  516. )
  517.  
  518.  
  519. ;;; Bessel functions.
  520.  
  521. ;;; Should generalize this to handle arbitrary precision!
  522.  
  523. (defun calcFunc-besJ (v x)
  524.   (or (math-numberp v) (math-reject-arg v 'numberp))
  525.   (or (math-numberp x) (math-reject-arg x 'numberp))
  526.   (let ((calc-internal-prec (min 8 calc-internal-prec)))
  527.     (math-with-extra-prec 3
  528.       (setq x (math-float (math-normalize x)))
  529.       (setq v (math-float (math-normalize v)))
  530.       (cond ((math-zerop x)
  531.          (if (math-zerop v)
  532.          '(float 1 0)
  533.            '(float 0 0)))
  534.         ((math-inexact-result))
  535.         ((not (math-num-integerp v))
  536.          (let ((start (math-div 1 (calcFunc-fact v))))
  537.            (math-mul (math-besJ-series start start
  538.                        0
  539.                        (math-mul '(float -25 -2)
  540.                              (math-sqr x))
  541.                        v)
  542.              (math-pow (math-div x 2) v))))
  543.         ((math-negp (setq v (math-trunc v)))
  544.          (if (math-oddp v)
  545.          (math-neg (calcFunc-besJ (math-neg v) x))
  546.            (calcFunc-besJ (math-neg v) x)))
  547.         ((eq v 0)
  548.          (math-besJ0 x))
  549.         ((eq v 1)
  550.          (math-besJ1 x))
  551.         ((Math-lessp v (math-abs-approx x))
  552.          (let ((j 0)
  553.            (bjm (math-besJ0 x))
  554.            (bj (math-besJ1 x))
  555.            (two-over-x (math-div 2 x))
  556.            bjp)
  557.            (while (< (setq j (1+ j)) v)
  558.          (setq bjp (math-sub (math-mul (math-mul j two-over-x) bj)
  559.                      bjm)
  560.                bjm bj
  561.                bj bjp))
  562.            bj))
  563.         (t
  564.          (if (Math-lessp 100 v) (math-reject-arg v 'range))
  565.          (let* ((j (logior (+ v (math-isqrt-small (* 40 v))) 1))
  566.             (two-over-x (math-div 2 x))
  567.             (jsum nil)
  568.             (bjp '(float 0 0))
  569.             (sum '(float 0 0))
  570.             (bj '(float 1 0))
  571.             bjm ans)
  572.            (while (> (setq j (1- j)) 0)
  573.          (setq bjm (math-sub (math-mul (math-mul j two-over-x) bj)
  574.                      bjp)
  575.                bjp bj
  576.                bj bjm)
  577.          (if (> (nth 2 (math-abs-approx bj)) 10)
  578.              (setq bj (math-mul bj '(float 1 -10))
  579.                bjp (math-mul bjp '(float 1 -10))
  580.                ans (and ans (math-mul ans '(float 1 -10)))
  581.                sum (math-mul sum '(float 1 -10))))
  582.          (or (setq jsum (not jsum))
  583.              (setq sum (math-add sum bj)))
  584.          (if (= j v)
  585.              (setq ans bjp)))
  586.            (math-div ans (math-sub (math-mul 2 sum) bj)))))))
  587. )
  588.  
  589. (defun math-besJ-series (sum term k zz vk)
  590.   (math-working "besJ" sum)
  591.   (setq k (1+ k)
  592.     vk (math-add 1 vk)
  593.     term (math-div (math-mul term zz) (math-mul k vk)))
  594.   (let ((next (math-add sum term)))
  595.     (if (math-nearly-equal next sum)
  596.     next
  597.       (math-besJ-series next term k zz vk)))
  598. )
  599.  
  600. (defun math-besJ0 (x &optional yflag)
  601.   (cond ((and (not yflag) (math-negp (calcFunc-re x)))
  602.      (math-besJ0 (math-neg x)))
  603.     ((Math-lessp '(float 8 0) (math-abs-approx x))
  604.      (let* ((z (math-div '(float 8 0) x))
  605.         (y (math-sqr z))
  606.         (xx (math-add x '(float (bigneg 164 398 785) -9)))
  607.         (a1 (math-poly-eval y
  608.                     '((float (bigpos 211 887 093 2) -16)
  609.                       (float (bigneg 639 370 073 2) -15)
  610.                       (float (bigpos 407 510 734 2) -14)
  611.                       (float (bigneg 627 628 098 1) -12)
  612.                       (float 1 0))))
  613.         (a2 (math-poly-eval y
  614.                     '((float (bigneg 152 935 934) -16)
  615.                       (float (bigpos 161 095 621 7) -16)
  616.                       (float (bigneg 651 147 911 6) -15)
  617.                       (float (bigpos 765 488 430 1) -13)
  618.                       (float (bigneg 995 499 562 1) -11))))
  619.         (sc (math-sin-cos-raw xx)))
  620.            (if yflag
  621.            (setq sc (cons (math-neg (cdr sc)) (car sc))))
  622.            (math-mul (math-sqrt
  623.               (math-div '(float (bigpos 722 619 636) -9) x))
  624.              (math-sub (math-mul (cdr sc) a1)
  625.                    (math-mul (car sc) (math-mul z a2))))))
  626.      (t
  627.       (let ((y (math-sqr x)))
  628.         (math-div (math-poly-eval y
  629.                       '((float (bigneg 456 052 849 1) -7)
  630.                     (float (bigpos 017 233 739 7) -5)
  631.                     (float (bigneg 418 442 121 1) -2)
  632.                     (float (bigpos 407 196 516 6) -1)
  633.                     (float (bigneg 354 590 362 13) 0)
  634.                     (float (bigpos 574 490 568 57) 0)))
  635.               (math-poly-eval y
  636.                       '((float 1 0)
  637.                     (float (bigpos 712 532 678 2) -7)
  638.                     (float (bigpos 853 264 927 5) -5)
  639.                     (float (bigpos 718 680 494 9) -3)
  640.                     (float (bigpos 985 532 029 1) 0)
  641.                     (float (bigpos 411 490 568 57) 0)))))))
  642. )
  643.  
  644. (defun math-besJ1 (x &optional yflag)
  645.   (cond ((and (math-negp (calcFunc-re x)) (not yflag))
  646.      (math-neg (math-besJ1 (math-neg x))))
  647.     ((Math-lessp '(float 8 0) (math-abs-approx x))
  648.      (let* ((z (math-div '(float 8 0) x))
  649.         (y (math-sqr z))
  650.         (xx (math-add x '(float (bigneg 491 194 356 2) -9)))
  651.         (a1 (math-poly-eval y
  652.                     '((float (bigneg 019 337 240) -15)
  653.                       (float (bigpos 174 520 457 2) -15)
  654.                       (float (bigneg 496 396 516 3) -14)
  655.                       (float 183105 -8)
  656.                       (float 1 0))))
  657.         (a2 (math-poly-eval y
  658.                     '((float (bigpos 412 787 105) -15)
  659.                       (float (bigneg 987 228 88) -14)
  660.                       (float (bigpos 096 199 449 8) -15)
  661.                       (float (bigneg 873 690 002 2) -13)
  662.                       (float (bigpos 995 499 687 4) -11))))
  663.         (sc (math-sin-cos-raw xx)))
  664.        (if yflag
  665.            (setq sc (cons (math-neg (cdr sc)) (car sc)))
  666.          (if (math-negp x)
  667.          (setq sc (cons (math-neg (car sc)) (math-neg (cdr sc))))))
  668.        (math-mul (math-sqrt (math-div '(float (bigpos 722 619 636) -9) x))
  669.              (math-sub (math-mul (cdr sc) a1)
  670.                    (math-mul (car sc) (math-mul z a2))))))
  671.     (t
  672.      (let ((y (math-sqr x)))
  673.        (math-mul
  674.         x
  675.         (math-div (math-poly-eval y
  676.                       '((float (bigneg 606 036 016 3) -8)
  677.                     (float (bigpos 826 044 157) -4)
  678.                     (float (bigneg 439 611 972 2) -3)
  679.                     (float (bigpos 531 968 423 2) -1)
  680.                     (float (bigneg 235 059 895 7) 0)
  681.                     (float (bigpos 232 614 362 72) 0)))
  682.               (math-poly-eval y
  683.                       '((float 1 0)
  684.                     (float (bigpos 397 991 769 3) -7)
  685.                     (float (bigpos 394 743 944 9) -5)
  686.                     (float (bigpos 474 330 858 1) -2)
  687.                     (float (bigpos 178 535 300 2) 0)
  688.                     (float (bigpos 442 228 725 144)
  689.                            0))))))))
  690. )
  691.  
  692. (defun calcFunc-besY (v x)
  693.   (math-inexact-result)
  694.   (or (math-numberp v) (math-reject-arg v 'numberp))
  695.   (or (math-numberp x) (math-reject-arg x 'numberp))
  696.   (let ((calc-internal-prec (min 8 calc-internal-prec)))
  697.     (math-with-extra-prec 3
  698.       (setq x (math-float (math-normalize x)))
  699.       (setq v (math-float (math-normalize v)))
  700.       (cond ((not (math-num-integerp v))
  701.          (let ((sc (math-sin-cos-raw (math-mul v (math-pi)))))
  702.            (math-div (math-sub (math-mul (calcFunc-besJ v x) (cdr sc))
  703.                    (calcFunc-besJ (math-neg v) x))
  704.              (car sc))))
  705.         ((math-negp (setq v (math-trunc v)))
  706.          (if (math-oddp v)
  707.          (math-neg (calcFunc-besY (math-neg v) x))
  708.            (calcFunc-besY (math-neg v) x)))
  709.         ((eq v 0)
  710.          (math-besY0 x))
  711.         ((eq v 1)
  712.          (math-besY1 x))
  713.         (t
  714.          (let ((j 0)
  715.            (bym (math-besY0 x))
  716.            (by (math-besY1 x))
  717.            (two-over-x (math-div 2 x))
  718.            byp)
  719.            (while (< (setq j (1+ j)) v)
  720.          (setq byp (math-sub (math-mul (math-mul j two-over-x) by)
  721.                      bym)
  722.                bym by
  723.                by byp))
  724.            by)))))
  725. )
  726.  
  727. (defun math-besY0 (x)
  728.   (cond ((Math-lessp (math-abs-approx x) '(float 8 0))
  729.      (let ((y (math-sqr x)))
  730.        (math-add
  731.         (math-div (math-poly-eval y
  732.                       '((float (bigpos 733 622 284 2) -7)
  733.                     (float (bigneg 757 792 632 8) -5)
  734.                     (float (bigpos 129 988 087 1) -2)
  735.                     (float (bigneg 036 598 123 5) -1)
  736.                     (float (bigpos 065 834 062 7) 0)
  737.                     (float (bigneg 389 821 957 2) 0)))
  738.               (math-poly-eval y
  739.                       '((float 1 0)
  740.                     (float (bigpos 244 030 261 2) -7)
  741.                     (float (bigpos 647 472 474) -4)
  742.                     (float (bigpos 438 466 189 7) -3)
  743.                     (float (bigpos 648 499 452 7) -1)
  744.                     (float (bigpos 269 544 076 40) 0))))
  745.         (math-mul '(float (bigpos 772 619 636) -9)
  746.               (math-mul (math-besJ0 x) (math-ln-raw x))))))
  747.     ((math-negp (calcFunc-re x))
  748.      (math-add (math-besJ0 (math-neg x) t)
  749.            (math-mul '(cplx 0 2)
  750.                  (math-besJ0 (math-neg x)))))
  751.     (t
  752.      (math-besJ0 x t)))
  753. )
  754.  
  755. (defun math-besY1 (x)
  756.   (cond ((Math-lessp (math-abs-approx x) '(float 8 0))
  757.      (let ((y (math-sqr x)))
  758.        (math-add
  759.         (math-mul
  760.          x
  761.          (math-div (math-poly-eval y
  762.                        '((float (bigpos 935 937 511 8) -6)
  763.                      (float (bigneg 726 922 237 4) -3)
  764.                      (float (bigpos 551 264 349 7) -1)
  765.                      (float (bigneg 139 438 153 5) 1)
  766.                      (float (bigpos 439 527 127) 4)
  767.                      (float (bigneg 943 604 900 4) 3)))
  768.                (math-poly-eval y
  769.                        '((float 1 0)
  770.                      (float (bigpos 885 632 549 3) -7)
  771.                      (float (bigpos 605 042 102) -3)
  772.                      (float (bigpos 002 904 245 2) -2)
  773.                      (float (bigpos 367 650 733 3) 0)
  774.                      (float (bigpos 664 419 244 4) 2)
  775.                      (float (bigpos 057 958 249) 5)))))
  776.         (math-mul '(float (bigpos 772 619 636) -9)
  777.               (math-sub (math-mul (math-besJ1 x) (math-ln-raw x))
  778.                 (math-div 1 x))))))
  779.     ((math-negp (calcFunc-re x))
  780.      (math-neg
  781.       (math-add (math-besJ1 (math-neg x) t)
  782.             (math-mul '(cplx 0 2)
  783.                   (math-besJ1 (math-neg x))))))
  784.     (t
  785.      (math-besJ1 x t)))
  786. )
  787.  
  788. (defun math-poly-eval (x coefs)
  789.   (let ((accum (car coefs)))
  790.     (while (setq coefs (cdr coefs))
  791.       (setq accum (math-add (car coefs) (math-mul accum x))))
  792.     accum)
  793. )
  794.  
  795.  
  796. ;;;; Bernoulli and Euler polynomials and numbers.
  797.  
  798. (defun calcFunc-bern (n &optional x)
  799.   (if (and x (not (math-zerop x)))
  800.       (if (and calc-symbolic-mode (math-floatp x))
  801.       (math-inexact-result)
  802.     (math-build-polynomial-expr (math-bernoulli-coefs n) x))
  803.     (or (math-num-natnump n) (math-reject-arg n 'natnump))
  804.     (if (consp n)
  805.     (progn
  806.       (math-inexact-result)
  807.       (math-float (math-bernoulli-number (math-trunc n))))
  808.       (math-bernoulli-number n)))
  809. )
  810.  
  811. (defun calcFunc-euler (n &optional x)
  812.   (or (math-num-natnump n) (math-reject-arg n 'natnump))
  813.   (if x
  814.       (let* ((n1 (math-add n 1))
  815.          (coefs (math-bernoulli-coefs n1))
  816.          (fac (math-div (math-pow 2 n1) n1))
  817.          (k -1)
  818.          (x1 (math-div (math-add x 1) 2))
  819.          (x2 (math-div x 2)))
  820.     (if (math-numberp x)
  821.         (if (and calc-symbolic-mode (math-floatp x))
  822.         (math-inexact-result)
  823.           (math-mul fac
  824.             (math-sub (math-build-polynomial-expr coefs x1)
  825.                   (math-build-polynomial-expr coefs x2))))
  826.       (calcFunc-collect
  827.        (math-reduce-vec
  828.         'math-add
  829.         (cons 'vec
  830.           (mapcar (function
  831.                (lambda (c)
  832.                  (setq k (1+ k))
  833.                  (math-mul (math-mul fac c)
  834.                        (math-sub (math-pow x1 k)
  835.                          (math-pow x2 k)))))
  836.               coefs)))
  837.        x)))
  838.     (math-mul (math-pow 2 n)
  839.           (if (consp n)
  840.           (progn
  841.             (math-inexact-result)
  842.             (calcFunc-euler n '(float 5 -1)))
  843.         (calcFunc-euler n '(frac 1 2)))))
  844. )
  845.  
  846. (defun math-bernoulli-coefs (n)
  847.   (let* ((coefs (list (calcFunc-bern n)))
  848.      (nn (math-trunc n))
  849.      (k nn)
  850.      (term nn)
  851.      coef
  852.      (calc-prefer-frac (or (integerp n) calc-prefer-frac)))
  853.     (while (>= (setq k (1- k)) 0)
  854.       (setq term (math-div term (- nn k))
  855.         coef (math-mul term (math-bernoulli-number k))
  856.         coefs (cons (if (consp n) (math-float coef) coef) coefs)
  857.         term (math-mul term k)))
  858.     (nreverse coefs))
  859. )
  860.  
  861. (defun math-bernoulli-number (n)
  862.   (if (= (% n 2) 1)
  863.       (if (= n 1)
  864.       '(frac -1 2)
  865.     0)
  866.     (setq n (/ n 2))
  867.     (while (>= n math-bernoulli-cache-size)
  868.       (let* ((sum 0)
  869.          (nk 1)     ; nk = n-k+1
  870.          (fact 1)   ; fact = (n-k+1)!
  871.          ofact
  872.          (p math-bernoulli-b-cache)
  873.          (calc-prefer-frac t))
  874.     (math-working "bernoulli B" (* 2 math-bernoulli-cache-size))
  875.     (while p
  876.       (setq nk (+ nk 2)
  877.         ofact fact
  878.         fact (math-mul fact (* nk (1- nk)))
  879.         sum (math-add sum (math-div (car p) fact))
  880.         p (cdr p)))
  881.     (setq ofact (math-mul ofact (1- nk))
  882.           sum (math-sub (math-div '(frac 1 2) ofact) sum)
  883.           math-bernoulli-b-cache (cons sum math-bernoulli-b-cache)
  884.           math-bernoulli-B-cache (cons (math-mul sum ofact)
  885.                        math-bernoulli-B-cache)
  886.           math-bernoulli-cache-size (1+ math-bernoulli-cache-size))))
  887.     (nth (- math-bernoulli-cache-size n 1) math-bernoulli-B-cache))
  888. )
  889.  
  890. ;;;   Bn = n! bn
  891. ;;;   bn = - sum_k=0^n-1 bk / (n-k+1)!
  892.  
  893. ;;; A faster method would be to use "tangent numbers", c.f., Concrete
  894. ;;; Mathematics pg. 273.
  895.  
  896. (setq math-bernoulli-b-cache '( (frac -174611
  897.                       (bigpos 0 200 291 698 662 857 802))
  898.                 (frac 43867 (bigpos 0 944 170 217 94 109 5))
  899.                 (frac -3617 (bigpos 0 880 842 622 670 10))
  900.                 (frac 1 (bigpos 600 249 724 74))
  901.                 (frac -691 (bigpos 0 368 674 307 1))
  902.                 (frac 1 (bigpos 160 900 47))
  903.                 (frac -1 (bigpos 600 209 1))
  904.                 (frac 1 30240) (frac -1 720)
  905.                 (frac 1 12) 1 ))
  906.  
  907. (setq math-bernoulli-B-cache '( (frac -174611 330) (frac 43867 798)
  908.                 (frac -3617 510) (frac 7 6) (frac -691 2730)
  909.                 (frac 5 66) (frac -1 30) (frac 1 42)
  910.                 (frac -1 30) (frac 1 6) 1 ))
  911.  
  912. (setq math-bernoulli-cache-size 11)
  913.  
  914.  
  915.  
  916. ;;; Probability distributions.
  917.  
  918. ;;; Binomial.
  919. (defun calcFunc-utpb (x n p)
  920.   (if math-expand-formulas
  921.       (math-normalize (list 'calcFunc-betaI p x (list '+ (list '- n x) 1)))
  922.     (calcFunc-betaI p x (math-add (math-sub n x) 1)))
  923. )
  924. (put 'calcFunc-utpb 'math-expandable t)
  925.  
  926. (defun calcFunc-ltpb (x n p)
  927.   (math-sub 1 (calcFunc-utpb x n p))
  928. )
  929. (put 'calcFunc-ltpb 'math-expandable t)
  930.  
  931. ;;; Chi-square.
  932. (defun calcFunc-utpc (chisq v)
  933.   (if math-expand-formulas
  934.       (math-normalize (list 'calcFunc-gammaQ (list '/ v 2) (list '/ chisq 2)))
  935.     (calcFunc-gammaQ (math-div v 2) (math-div chisq 2)))
  936. )
  937. (put 'calcFunc-utpc 'math-expandable t)
  938.  
  939. (defun calcFunc-ltpc (chisq v)
  940.   (if math-expand-formulas
  941.       (math-normalize (list 'calcFunc-gammaP (list '/ v 2) (list '/ chisq 2)))
  942.     (calcFunc-gammaP (math-div v 2) (math-div chisq 2)))
  943. )
  944. (put 'calcFunc-ltpc 'math-expandable t)
  945.  
  946. ;;; F-distribution.
  947. (defun calcFunc-utpf (f v1 v2)
  948.   (if math-expand-formulas
  949.       (math-normalize (list 'calcFunc-betaI
  950.                 (list '/ v2 (list '+ v2 (list '* v1 f)))
  951.                 (list '/ v2 2)
  952.                 (list '/ v1 2)))
  953.     (calcFunc-betaI (math-div v2 (math-add v2 (math-mul v1 f)))
  954.             (math-div v2 2)
  955.             (math-div v1 2)))
  956. )
  957. (put 'calcFunc-utpf 'math-expandable t)
  958.  
  959. (defun calcFunc-ltpf (f v1 v2)
  960.   (math-sub 1 (calcFunc-utpf f v1 v2))
  961. )
  962. (put 'calcFunc-ltpf 'math-expandable t)
  963.  
  964. ;;; Normal.
  965. (defun calcFunc-utpn (x mean sdev)
  966.   (if math-expand-formulas
  967.       (math-normalize
  968.        (list '/
  969.          (list '+ 1
  970.            (list 'calcFunc-erf
  971.              (list '/ (list '- mean x)
  972.                    (list '* sdev (list 'calcFunc-sqrt 2)))))
  973.          2))
  974.     (math-mul (math-add '(float 1 0)
  975.             (calcFunc-erf
  976.              (math-div (math-sub mean x)
  977.                    (math-mul sdev (math-sqrt-2)))))
  978.           '(float 5 -1)))
  979. )
  980. (put 'calcFunc-utpn 'math-expandable t)
  981.  
  982. (defun calcFunc-ltpn (x mean sdev)
  983.   (if math-expand-formulas
  984.       (math-normalize
  985.        (list '/
  986.          (list '+ 1
  987.            (list 'calcFunc-erf
  988.              (list '/ (list '- x mean)
  989.                    (list '* sdev (list 'calcFunc-sqrt 2)))))
  990.          2))
  991.     (math-mul (math-add '(float 1 0)
  992.             (calcFunc-erf
  993.              (math-div (math-sub x mean)
  994.                    (math-mul sdev (math-sqrt-2)))))
  995.           '(float 5 -1)))
  996. )
  997. (put 'calcFunc-ltpn 'math-expandable t)
  998.  
  999. ;;; Poisson.
  1000. (defun calcFunc-utpp (n x)
  1001.   (if math-expand-formulas
  1002.       (math-normalize (list 'calcFunc-gammaP x n))
  1003.     (calcFunc-gammaP x n))
  1004. )
  1005. (put 'calcFunc-utpp 'math-expandable t)
  1006.  
  1007. (defun calcFunc-ltpp (n x)
  1008.   (if math-expand-formulas
  1009.       (math-normalize (list 'calcFunc-gammaQ x n))
  1010.     (calcFunc-gammaQ x n))
  1011. )
  1012. (put 'calcFunc-ltpp 'math-expandable t)
  1013.  
  1014. ;;; Student's t.  (As defined in Abramowitz & Stegun and Numerical Recipes.)
  1015. (defun calcFunc-utpt (tt v)
  1016.   (if math-expand-formulas
  1017.       (math-normalize (list 'calcFunc-betaI
  1018.                 (list '/ v (list '+ v (list '^ tt 2)))
  1019.                 (list '/ v 2)
  1020.                 '(float 5 -1)))
  1021.     (calcFunc-betaI (math-div v (math-add v (math-sqr tt)))
  1022.             (math-div v 2)
  1023.             '(float 5 -1)))
  1024. )
  1025. (put 'calcFunc-utpt 'math-expandable t)
  1026.  
  1027. (defun calcFunc-ltpt (tt v)
  1028.   (math-sub 1 (calcFunc-utpt tt v))
  1029. )
  1030. (put 'calcFunc-ltpt 'math-expandable t)
  1031.  
  1032.  
  1033.  
  1034.  
  1035.